package com.ndp.fb.mq.service.publishhandleservice.post;

import com.alibaba.dubbo.common.json.JSON;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONObject;
import com.ndp.ec.core.api.DPAAdPerformService;
import com.ndp.fb.constant.CommonConstants;
import com.ndp.fb.enums.adgroupstatus.AdGroupStatus;
import com.ndp.fb.enums.publish.PublishStatus;
import com.ndp.fb.exception.CheckedException;
import com.ndp.fb.model.fbagent.result.ReDownloadObject;
import com.ndp.fb.model.fbagent.result.adgroup.AdGroupReDownload;
import com.ndp.fb.model.fbagent.result.adgroup.FbAdgroup;
import com.ndp.fb.mongo.api.AdGroupMongoService;
import com.ndp.fb.mongo.api.AdMarketTargetMongoService;
import com.ndp.fb.mongo.model.FBAdForMongo;
import com.ndp.fb.mongo.model.PromotedObject;
import com.ndp.fb.mongo.model.autocreatead.AdMarketTarget;
import com.ndp.fb.mq.api.service.publishhandleservice.PublishPostProcessor;
import com.ndp.fb.mq.api.service.publishhandleservice.PublishPostResult;
import com.ndp.fb.mq.service.schedulerservice.adpublish.PublishCacheMongoServiceFailover;
import com.ndp.fb.rdb.api.AdCampaignRdbService;
import com.ndp.fb.rdb.api.AdCreativeRdbService;
import com.ndp.fb.rdb.api.AdRdbService;
import com.ndp.fb.rdb.api.AdSetRdbService;
import com.ndp.fb.rdb.api.EntrustAccountRdbService;
import com.ndp.fb.rdb.model.AdCampaignGroup;
import com.ndp.fb.rdb.model.AdGroup;
import com.ndp.fb.rdb.model.EntrustAccount;
import com.ndp.fb.redis.model.AdGroupLevel;
import com.ndp.fb.util.DateUtil;
import com.ndp.fb.util.StringUtil;
import com.restfb.DefaultJsonMapper;
import com.restfb.JsonMapper;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

/**
 * 广告发布完成后，回填业务数据的实现
 * Created by hunk.qin on 2016/1/4.
 */
@Component
public class  PublishPostBackFillForBusinessData implements PublishPostProcessor {

    private static Logger logger = LoggerFactory.getLogger(PublishPostBackFillForBusinessData.class);
    private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
    @Autowired
    private PublishCacheMongoServiceFailover publishCacheMongoService;

    @Reference
    private AdRdbService adGroupRdbService;

    @Reference
    private AdCreativeRdbService adCreativeRdbService;

    @Reference
    private AdCampaignRdbService adCampaignRdbService;

    @Reference
    private AdSetRdbService adSetRdbService;

    @Reference
    private AdGroupMongoService adGroupMongoService;
    @Reference
    private DPAAdPerformService dPAAdPerformService;
    
    @Reference
    private AdMarketTargetMongoService adMarketTargetMongoService;

    @Reference
    private EntrustAccountRdbService entrustAccountRdbService;
    @Override
    public void processor(PublishPostResult publishPostResult) {
        if(publishPostResult.getPublishStatus()== PublishStatus.SUCCEED){
            try {
                AdGroupLevel adGroupLevel = (AdGroupLevel) publishPostResult.getBaseAdLevel();
                ReDownloadObject reDownLoad = (ReDownloadObject)publishPostResult.getPostResult();
                String adGroupId=publishPostResult.getParatms().get("adGroupId");
                adGroupLevel.setAdGroupId(adGroupId);
                // 回填业务数据。
                AdGroupReDownload o = JSON.parse(reDownLoad.getData(), AdGroupReDownload.class);
                String adJson = JSONObject.toJSONString(o.getAds().get(adGroupId));
                updateAdGroupBusiness(adJson, adGroupLevel);
                //update mongo and mysql
                updateDPAAdAttr(adGroupLevel);
                updateMarketTargetAdAttr(reDownLoad.getData(),adGroupLevel);
            }catch (Exception e){
                logger.error("广告发布成功后，回填业务数据失败！params==={},redonwload obj{}",
                        JSONObject.toJSONString(publishPostResult.getParatms()),JSONObject.toJSON(publishPostResult.getPostResult()),e.getMessage(),e);
            }
        }else{
            logger.info("广告发布失败,不进行业务数据回填.",
                    JSONObject.toJSONString(publishPostResult.getParatms()),JSONObject.toJSON(publishPostResult.getPostResult()));
        }

    }

    private void updateDPAAdAttr(AdGroupLevel adGroupLevel) {
        String dpaAttrStr = publishCacheMongoService.findDPAAttribute(adGroupLevel.getPublishBatchId());
        if(StringUtil.isNotEmpty(dpaAttrStr)){
            Map dpaAttrMap  = com.alibaba.fastjson.JSON.parseObject(dpaAttrStr, Map.class);
            adGroupMongoService.updateAdForMongo(Long.valueOf(adGroupLevel.getAdGroupId()), dpaAttrMap);
            //系统创建的广告默认关联到营销目标下
            Long feed_id = Long.valueOf(dpaAttrMap.get(CommonConstants.WE_FEED_ID).toString());
            List<AdMarketTarget> adMarketTargets = adMarketTargetMongoService.getAdMarketTargetByFeedId(feed_id);
            
            if(!CollectionUtils.isEmpty(adMarketTargets)){
            	dpaAttrMap.put("adMarketTargetId", adMarketTargets.get(0).getId());
            }else{
            	
            }
            adGroupMongoService.updateAdForMongo(Long.valueOf(adGroupLevel.getAdGroupId()), dpaAttrMap);
            
            //update mysql creative camp adset ad maritectid and adset producet set id
            Long materieId= Long.valueOf(dpaAttrMap.get(CommonConstants.MATERIE_ID).toString());
            String productSetid=dpaAttrMap.get(CommonConstants.PRODUCT_SET_ID).toString();
            adGroupRdbService.updateEcTemplateMaterielId(Long.valueOf(adGroupLevel.getAdGroupId()),materieId);
            adSetRdbService.updateEcTemplateMaterielId(adGroupLevel.getAdSetId(),materieId);
            adSetRdbService.updateProductSetMongoId(productSetid,adGroupLevel.getAdSetId());
            adCampaignRdbService.updateEcTemplateMaterielId(adGroupLevel.getAdCampaignGroupId(),materieId);
            adCreativeRdbService.updateEcTemplateMaterielId(adGroupLevel.getAdCreativeId(),materieId);
        }
    }
    private void updateMarketTargetAdAttr(String adJson,AdGroupLevel adGroupLevel) throws CheckedException {
    	//如果是自动优化创建的广告这里callback纪录ad
        String marketTargetAttribute = publishCacheMongoService.findMarketTargetAttribute(adGroupLevel.getPublishBatchId());
        
        Long ad_id = Long.valueOf(adGroupLevel.getAdGroupId());
        if(StringUtils.isNotEmpty(marketTargetAttribute)){
        	JSONObject marketObj = JSONObject.parseObject(marketTargetAttribute);
        	if(!marketObj.isEmpty()){
        		Map dpaAttrMap  = com.alibaba.fastjson.JSON.parseObject(marketTargetAttribute, Map.class);
                adGroupMongoService.updateAdForMongo(Long.valueOf(adGroupLevel.getAdGroupId()), dpaAttrMap);
                JSONObject obj = JSONObject.parseObject(marketTargetAttribute);
            	obj.put("ad_id", ad_id);
            	FBAdForMongo fbAdForMongo = this.getAdGroupForMongo(ad_id,JSONObject.parseObject(adJson));
            	obj.put("ad", fbAdForMongo);
            	dPAAdPerformService.createAdCallback(obj);
        	}
        	
        }
    }
    private void updateAdGroupBusiness(String adJson, AdGroupLevel adGroupLevel) {
        JsonMapper jsonMapper = new DefaultJsonMapper();
        FbAdgroup fbAdgroup = jsonMapper.toJavaObject(adJson, FbAdgroup.class);
        AdGroup adGroup = buildAdGroup(fbAdgroup, adGroupLevel);
        adGroupRdbService.save(adGroup);
    }

    /**
     * 构造adgroup
     *
     * @param adGroupLevel
     * @return
     */
    private AdGroup buildAdGroup(FbAdgroup fbAdgroup, AdGroupLevel adGroupLevel) {
        AdGroup adGroup = new AdGroup();
        Date now = new Date();
        adGroup.setFbAccountId(fbAdgroup.getAccountId());
        adGroup.setAdGroupId(fbAdgroup.getId());
        adGroup.setBidInfo(fbAdgroup.getBidInfo());
        adGroup.setBidType(fbAdgroup.getBidType());
        adGroup.setAdSetId(fbAdgroup.getCampaignId());
        adGroup.setCampaignGroupId(fbAdgroup.getCampaignGroupId());
        adGroup.setAdCreativeId(adGroupLevel.getAdCreativeId());
        adGroup.setName(fbAdgroup.getName());
        adGroup.setAdGroupStatus(AdGroupStatus.PENDING_REVIEW.getStatus());
        adGroup.setConversionSpecs(fbAdgroup.getConversionSpecs());
        adGroup.setFbConnectionObjectId(adGroupLevel.getFbConnectionObjectId());
        adGroup.setCreatedTime(now);
        adGroup.setCreatedUtcTime(now.getTime());
        adGroup.setUpdatedTime(now);
        adGroup.setUpdatedUtcTime(now.getTime());
        adGroup.setPublishBatchId(adGroupLevel.getPublishBatchId());
        adGroup.setProductConfId(adGroupLevel.getProductConfigurationId());
        //2.4
        adGroup.setBidAmount(fbAdgroup.getBidAmount());
        return adGroup;
    }

    private FBAdForMongo getAdGroupForMongo(Long ad_id,JSONObject data) {
    	JSONObject objMap = data.getJSONObject("ads").getJSONObject(""+ad_id);
		FBAdForMongo adForMongo = new FBAdForMongo();
		adForMongo.setAccount_id(objMap.getLongValue("account_id"));
		
		EntrustAccount entrustAccount = entrustAccountRdbService.findFromCahe(objMap.getLongValue("account_id"));
		
		adForMongo.setAd_id(objMap.getLongValue("id"));
		adForMongo.setAd_review_feedback(JSONObject.parseObject(
				objMap.get("ad_review_feedback") == null ? null : objMap.getString("ad_review_feedback"), Map.class));
		adForMongo.setAdlabels(JSONObject
				.parseArray(objMap.get("adlabels") == null ? null : objMap.getString("adlabels"), List.class));

		JSONObject adset = objMap.getJSONObject("adset");
//		if (adset != null) {
//			adset.put("campaign_id", adset.getLongValue("campaign_id"));
//			adset.put("account_id", adset.getLongValue("account_id"));
//			adset.put("adset_id", adset.getLongValue("id"));
//			adset.put("lifetime_budget", adset.getLongValue("lifetime_budget"));
//			adset.put("daily_budget", adset.getLongValue("daily_budget"));
//			adset.put("budget_remaining", adset.getLongValue("budget_remaining"));
//
//			adset.remove("id");
//			// 生成时间
//			Calendar cCreateTime = DateUtil.FbDateToJavaDate(adset.getString("created_time"));
//			Calendar cUpdateTime = DateUtil.FbDateToJavaDate(adset.getString("updated_time"));
//
//			Calendar cStartTime = DateUtil.FbDateToJavaDate(adset.getString("start_time"));
//			Calendar cEndTime = DateUtil.FbDateToJavaDate(adset.getString("end_time"));
//
//			adset.put("created_time", adset.getString("created_time"));
//			adset.put("updated_time", adset.getString("updated_time"));
//			adset.put("start_time", adset.getString("start_time"));
//			if (cEndTime == null) {
//				adset.put("end_time", "");
//			}
//			adset.put("created_utc_time", cCreateTime.getTimeInMillis());
//			adset.put("updated_utc_time", cUpdateTime.getTimeInMillis());
//			adset.put("start_utc_time", cStartTime.getTimeInMillis());
//
//			if (cEndTime == null) {
//				adset.put("end_utc_time", 0);
//			} else {
//				adset.put("end_utc_time", cEndTime.getTimeInMillis());
//			}
//			JSONObject promoted_object = adset.getJSONObject("promoted_object");
//			if (promoted_object != null) {
//				PromotedObject promotedObject = JSONObject.parseObject(promoted_object.toJSONString(),
//						PromotedObject.class);
//				adset.put("promoted_object", promotedObject);
//				if (StringUtils.isNotBlank(promotedObject.getObject_store_url())) {
//					if (promotedObject.getObject_store_url().indexOf("google") > -1) {
//						adForMongo.setPlatform("google_play");
//					}
//					if (promotedObject.getObject_store_url().indexOf("itunes") > -1) {
//						adForMongo.setPlatform("itunes");
//					}
//				}
//			}
//			adForMongo.setAdSet(adset);
//		}
		adForMongo.setAdset_id(objMap.getLongValue("adset_id"));
		adForMongo.setBid_amount(objMap.getIntValue("bid_amount"));
		adForMongo.setBid_info(JSONObject
				.parseObject(objMap.get("bid_info") == null ? null : objMap.getString("bid_info"), Map.class));
		adForMongo.setBid_type(objMap.getString("bid_type"));
//		JSONObject campaign = objMap.getJSONObject("campaign");
//		if (campaign != null) {
//			campaign.put("campaign_id", campaign.getLongValue("id"));
//			campaign.remove("id");
//			campaign.put("account_id", campaign.getLongValue("account_id"));
//
//			// 生成时间
//			// 生成时间
//			Calendar cCreateTime = DateUtil.FbDateToJavaDate(campaign.getString("created_time"));
//			Calendar cUpdateTime = DateUtil.FbDateToJavaDate(campaign.getString("updated_time"));
//
//			Calendar cStartTime = DateUtil.FbDateToJavaDate(campaign.getString("start_time"));
//			Calendar cEndTime = DateUtil.FbDateToJavaDate(campaign.getString("stop_time"));
//
//			campaign.put("created_time", campaign.getString("created_time"));
//			campaign.put("updated_time", campaign.getString("updated_time"));
//			campaign.put("start_time", campaign.getString("start_time"));
//			if (cEndTime == null) {
//				campaign.put("end_time", "");
//			}
//			campaign.put("created_utc_time", cCreateTime.getTimeInMillis());
//			campaign.put("updated_utc_time", cUpdateTime.getTimeInMillis());
//			campaign.put("start_utc_time", cStartTime.getTimeInMillis());
//			if (cEndTime == null) {
//				campaign.put("end_utc_time", 0);
//			} else {
//				campaign.put("end_utc_time", cEndTime.getTimeInMillis());
//			}
//			adForMongo.setCampaign(campaign);
//		}
		// JSONObject creative = objMap.getJSONObject("creative");
		// if(creative!=null){
		// JSONObject object_story_spec =
		// creative.getJSONObject("object_story_spec");
		// if(object_story_spec!=null){
		// if(object_story_spec.getJSONObject("link_data")!=null){
		// JSONObject link_data = object_story_spec.getJSONObject("link_data");
		// if(link_data.getJSONArray("child_attachments")!=null){
		// //轮播图广告
		// }else{
		// //普通广告
		//
		// }
		// }
		// }
		// }
		adForMongo.setCampaign_id(objMap.getLongValue("campaign_id"));
		adForMongo.setConfigured_status(objMap.getString("configured_status"));
		adForMongo.setConversion_specs(JSONObject.parseObject(
				objMap.get("conversion_specs") == null ? null : objMap.getString("conversion_specs"), List.class));

		// 生成时间
		Calendar cCreateTime = Calendar.getInstance();
		cCreateTime.setTimeInMillis(objMap.getLongValue("created_time")*1000);
		Calendar cUpdateTime = Calendar.getInstance();
		cUpdateTime.setTimeInMillis(objMap.getLongValue("updated_time")*1000);
		format.setTimeZone(TimeZone.getTimeZone(entrustAccount.getTimezone()));
		adForMongo.setCreated_time(format.format(cCreateTime.getTime()));
		adForMongo.setUpdated_time(format.format(cUpdateTime.getTime()));
		
		adForMongo.setCreated_utc_time(cCreateTime == null ? null : cCreateTime.getTimeInMillis());
		adForMongo.setUpdated_utc_time(cUpdateTime == null ? null : cUpdateTime.getTimeInMillis());
		JSONObject creatives = data.getJSONObject("creatives");
		if(creatives!=null){
			for(String key:creatives.keySet()){
				adForMongo.setCreative(JSONObject.parseObject(creatives.getString(key), Map.class));
			}
		}
		
		adForMongo.setEffective_status(objMap.getString("effective_status"));
		adForMongo.setLast_updated_by_app_id(objMap.getLongValue("last_updated_by_app_id"));
		adForMongo.setName(objMap.getString("name"));
		adForMongo.setTracking_specs(JSONObject.parseObject(
				objMap.get("tracking_specs") == null ? null : objMap.getString("tracking_specs"), List.class));
		adForMongo.setFailed_delivery_checks(JSONObject.parseObject(
				objMap.get("failed_delivery_checks") == null ? null : objMap.getString("failed_delivery_checks"),
				List.class));
		return adForMongo;
	}
    public static void main(String[] args) {
    	System.out.println(format.format(Calendar.getInstance().getTime()));
	}
}
